/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package bgu.sonar.util.ui.nodes;

import bgu.sonar.util.collections.obs.ObservableList;
import bgu.sonar.util.ui.DNDs;
import bgu.sonar.util.ui.visual.HasVisualData;
import bgu.sonar.util.ui.visual.VisualDataProvider;
import java.awt.Image;
import java.awt.datatransfer.Transferable;
import java.io.IOException;
import java.util.Collection;
import javax.swing.Action;
import org.openide.nodes.AbstractNode;
import org.openide.nodes.Children;

/**
 *
 * @author bennyl
 */
public class ExtendableNode<T> extends AbstractNode implements HasVisualData {

    private T model = null;
    private Image icon = null;
    private ActionProvider actionProvider = null;

    public ExtendableNode() {
        super(Children.LEAF);
    }

    public ExtendableNode(T model) {
        super(Children.LEAF);
        this.model = model;

        HasVisualData v = HasVisualData.Support.extract(model);
        setName(v.getVisualName());
        icon = v.getIcon();
    }

    public void setActionProvider(ActionProvider actionProvider) {
        this.actionProvider = actionProvider;
    }

    public ActionProvider getActionProvider() {
        return actionProvider;
    }

    public ExtendableNode(T model, VisualDataProvider vprovider) {
        super(Children.LEAF);
        this.model = model;

        HasVisualData v = vprovider.provideFor(model);
        setName(v.getVisualName());
        icon = v.getIcon();
    }

    /**
     * return true if the model is not null and its type is the given
     *
     * @param modelType
     * @return
     */
    public boolean hasModelType(Class modelType) {
        if (model == null) {
            return false;
        }
        return modelType.isAssignableFrom(model.getClass());
    }

    public void setIcon(Image icon) {
        this.icon = icon;
    }

    public T getModel() {
        return model;
    }

    @Override
    public final Action getPreferredAction() {
        new NodeDoubleClickedEvent(this).post();
        if (actionProvider != null) {
            return actionProvider.provideDefaultActionFor(getModel());
        }
        return null;

    }

    @Override
    public Image getIcon(int type) {
        if (icon == null) {
            return super.getIcon(type); //To change body of generated methods, choose Tools | Templates.
        }

        return icon;
    }

    @Override
    public Image getOpenedIcon(int type) {
        if (icon == null) {
            return super.getOpenedIcon(type); //To change body of generated methods, choose Tools | Templates.
        }

        return icon;
    }

    @Override
    public final Action[] getActions(boolean context) {
        if (actionProvider == null) {
            return new Action[0];
        }
        Collection<Action> actions = actionProvider.provideFor(getModel());
        return actions.toArray(new Action[actions.size()]);
    }

    @Override
    public Image getIcon() {
        return getIcon(16);
    }

    @Override
    public boolean canCopy() {
        return true;
    }

    @Override
    public Transferable clipboardCopy() throws IOException {
        DNDs.setDrag(getModel());
        return super.clipboardCopy(); //To change body of generated methods, choose Tools | Templates.
    }

    public void setChildrenList(ObservableList children) {
        setChildren(Children.create(new ListNode.ListNodeChildren(children, new ListNode.DefaultValueNodeFactory()), true));
    }

    @Override
    public String getVisualName() {
        return getName();
    }

    void setAttributes(CategoryNodeAttributes attr) {
        setActionProvider(attr.getCategoryActionsProvider());
        setName(attr.getVisualName());
        setIcon(attr.getIcon());
    }

    @Override
    public String getDescription() {
        return "";
    }
}
